package com.cus.tom.transfer.trans.service;

import static com.cus.tom.transfer.trans.io.DirectoryReader.LOG_TAG;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PowerManager;
import android.util.Log;

import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.documentfile.provider.DocumentFile;

import com.cus.tom.transfer.App;
import com.cus.tom.transfer.BuildConfig;
import com.cus.tom.transfer.R;
import com.cus.tom.transfer.bean.Const;
import com.cus.tom.transfer.trans.io.ProgressReporter;
import com.plata.base.utils.WeakHandler;


public abstract class TransferService extends Service {
    final static int TcpBufferSize = 512 * 1024;
    final static int BufferSize = 512 * 1024;
    private static PowerManager.WakeLock wakeLock = null;
    private static WifiManager.WifiLock wifiLock = null;
    final WeakHandler handler = new WeakHandler(Looper.myLooper());
    DocumentFile root = null;
    Notification.Builder builder;
    NotificationManager notificationManager = null;
    Thread thread = null;
    int startId = 0;
    boolean result = false;

    void acquireLocks() {
        releaseLocks();
        PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        if (powerManager != null) {
            wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG + ":TransferService");
            wakeLock.acquire(10 * 60 * 1000L /*10 minutes*/);
            Log.d(LOG_TAG, "WakeLock acquired for 10 minutes");
        }
        WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
        if (wifiManager != null) {
            wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, LOG_TAG);
            wifiLock.acquire();
            Log.d(LOG_TAG, "WifiLock acquired");
        }
    }

    void releaseLocks() {
        if (wakeLock != null) {
            if (wakeLock.isHeld()) {
                wakeLock.release();
                Log.d(LOG_TAG, "WakeLock released");
            }
            wakeLock = null;
        }
        if (wifiLock != null) {
            if (wifiLock.isHeld()) {
                wifiLock.release();
                Log.d(LOG_TAG, "WifiLock released");
            }
            wifiLock = null;
        }
    }

    void initNotification(@StringRes int title) {
        notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        if (builder == null) {
            builder = new Notification.Builder(this.getApplicationContext());
        }

        builder.setContentIntent(null)
                .setContentTitle(getString(title))
                .setSmallIcon(R.drawable.ic_send_black_24dp)
                .setWhen(System.currentTimeMillis())
                .setProgress(0, 0, true)
                .setOngoing(true)
                .setOnlyAlertOnce(true)
                .setVisibility(Notification.VISIBILITY_PUBLIC);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Android 8.0+
            final NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            if (manager != null) {
                App.getApp().createNotificationChannels(manager, getResources());
                builder.setChannelId(Const.CHANNEL_TRANSFER_STATE);
            }
        } else {
            // Android 7.1
            builder.setPriority(Notification.PRIORITY_DEFAULT)
                    .setLights(0, 0, 0)
                    .setVibrate(null)
                    .setSound(null);
        }

        final Intent cancel = new Intent(this, this.getClass());
        cancel.setAction("cancel");
        builder.addAction(new Notification.Action.Builder(null, getResources().getString(R.string.cancel),
                        PendingIntent.getService(this, startId, cancel, PendingIntent.FLAG_IMMUTABLE)).build())
                .setContentText(getResources().getString(R.string.notification_starting));

        startForeground(startId, builder.build());
    }

    @CallSuper
    @Override
    public void onDestroy() {
        notificationManager = null;
        postUpdateButton();
        releaseLocks();
        super.onDestroy();
    }

    void postUpdateButton() {
//		final App mainActivity = ((App) getApplicationContext()).mainActivity;
//		if (mainActivity != null) {
//			mainActivity.handler.post(mainActivity::updateButtons);
//		}
    }

    protected void stop() {
        if (thread != null) {
            thread.interrupt();
            thread = null;
        }
        builder = null;
        releaseLocks();
        stopSelf();
    }

    void showResult() {
        if (notificationManager == null) {
            return;
        }
        final Notification.Builder builder = new Notification.Builder(this.getApplicationContext());

        if (result) {
            builder.setContentTitle(getResources().getString(R.string.transfer_success))
                    .setSmallIcon(R.drawable.ic_done_black_24dp);
        } else {
            builder.setContentTitle(getResources().getString(R.string.transfer_failed))
                    .setSmallIcon(R.drawable.ic_error_outline_black_24dp);
        }

        builder.setContentIntent(null)
                .setWhen(System.currentTimeMillis())
                .setOngoing(false)
                .setVisibility(Notification.VISIBILITY_PUBLIC);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Android 8.0+
            NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            if (manager != null) {
                builder.setChannelId(Const.CHANNEL_TRANSFER_RESULT);
            }
            builder.setTimeoutAfter(10000);
        } else {
            // Android 7.1
            builder.setPriority(Notification.PRIORITY_DEFAULT);
        }

        notificationManager.notify(startId, builder.build());
    }

    public static class Progress implements ProgressReporter, Parcelable {
        public String text;
        public long now, max;
        public int current, total;

        protected Progress() {

        }

        protected Progress(Parcel in) {
            text = in.readString();
            now = in.readLong();
            max = in.readLong();
            current = in.readInt();
            total = in.readInt();
        }

        public static final Creator<Progress> CREATOR = new Creator<Progress>() {
            @Override
            public Progress createFromParcel(Parcel in) {
                return new Progress(in);
            }

            @Override
            public Progress[] newArray(int size) {
                return new Progress[size];
            }
        };

        synchronized Progress get() {
            Progress p = new Progress();
            p.text = text;
            p.now = now;
            p.max = max;
            p.current = current;
            p.total = total;
            return p;
        }

        @Override
        public synchronized void report(String text, long now, long max, int current, int total) {
            this.text = text;
            this.now = now;
            this.max = max;
            this.current = current;
            this.total = total;
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            dest.writeString(text);
            dest.writeLong(now);
            dest.writeLong(max);
            dest.writeInt(current);
            dest.writeInt(total);
        }
    }

    @Override
    public void sendBroadcast(Intent intent) {
        intent.setPackage(BuildConfig.APPLICATION_ID);
        super.sendBroadcast(intent);
    }
}
